/**
 * This script contains tests for the FlyTED Sparql Endpoint.
 * @author Alistair Miles
 * @author Jun Zhao
 */
// convenience variables
var Assert = YAHOO.util.Assert;
var log = YAHOO.log;
var JSON = YAHOO.lang.JSON;
var sparqlns = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ";
sparqlns += "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> ";
sparqlns += "PREFIX dro: <http://imageweb.zoo.ox.ac.uk/drosophila#> ";


function testEndpointExists(testcase) {

	// define the callback object
	var callback = {
		success: testEndpointExistsResponseSuccess(testcase),
		failure: testEndpointExistsResponseFailure(testcase)
	};
	
	log("Make the request");
	var request = YAHOO.util.Connect.asyncRequest("GET", "flyted", callback, null);
	
	log("Suspend the test runner");
	testcase.wait();
	
	log("N.B. this code should never be reached.");
}

function testEndpointHasData(testcase) {
	var query = "ASK { ?subject ?predicate ?object }";
	testAskQuery("flyted", testcase, query, true, "Endpoint has no data.");
}

function testEndpointHasImages(testcase) {
	var query = "ASK { ?image rdf:type dro:Image }";
	testAskQuery("flyted", testcase, query, true, "Endpoint has no images.");
}

function testEndpointImageURIsAreValid(testcase) {
	var query = "ASK { ?image rdf:type dro:Image FILTER ( isIRI(?image) && regex(str(?image), '^http://') ) }";
	testAskQuery("flyted", testcase, query, true, "Expected image URIs to start with 'http://'.");
}

function testEndpointHasImagesWithGeneNames(testcase) {
	var query = "ASK { ?image rdf:type dro:Image ; dro:genename ?genename . }";
	testAskQuery("flyted", testcase, query, true, "Endpoint has no images with gene names.");
}

function testEndpointHasNoImagesWithoutGeneNames(testcase) {
	var query = "ASK { ?image rdf:type dro:Image . OPTIONAL {?image dro:genename ?genename }. FILTER ( !bound(?genename)) }";
	testAskQuery("flyted", testcase, query, false, "Expected no images without gene names.");	
}

function testEndpointHasImagesWithSpecificGeneName(testcase, genename) {
	var query = "ASK {?image dro:genename '"+genename+"'}";
	var message = "There should be at least one image for gene '"+genename+"'.";
	testAskQuery("flyted", testcase, query, true, message);	
}

function testEndpointHasImageWithThumbnails (testcase) {
	var query = "ASK { ?image rdf:type dro:Image ; dro:thumbnail ?thumbnail . }";
	testAskQuery("flyted", testcase, query, true, "Endpoint has no images with thumbnails.");
}

function testEndpointHasNoImagesWithoutThumbnails (testcase) {
	var query = "ASK { ?image rdf:type dro:Image . OPTIONAL {?image dro:thumbnail ?thumbnail }. FILTER ( !bound(?thumbnail)) }";
	testAskQuery("flyted", testcase, query, false, "Endpoint has images without thumbnails.");
}

function testEndpointHasImageWithSeeAlso (testcase) {
	var query = "ASK { ?image rdf:type dro:Image ; rdfs:seeAlso ?seeAlso . }";
	testAskQuery("flyted", testcase, query, true, "Expected images are linked with a see also.");
}

function testEndpointHasNoImagesWithoutSeeAlso (testcase) {
	var query = "ASK { ?image rdf:type dro:Image . OPTIONAL {?image rdfs:seeAlso ?seeAlso }. FILTER ( !bound(?seeAlso)) }";
	testAskQuery("flyted", testcase, query, false, "Expected no images without linked with a see also.");
}

function testEndpointHasImageWithGenotype(testcase) {
	var query = "ASK { ?image rdf:type dro:Image ; dro:genotype ?genotype . }";
	testAskQuery("flyted", testcase, query, true, "Expected images with a genotype.");
}

function testEndpointHasNoImagesWithoutGenotype (testcase) {
	var query = "ASK { ?image rdf:type dro:Image . OPTIONAL {?image dro:genotype ?genotype }. FILTER ( !bound(?genotype)) }";
	testAskQuery("flyted", testcase, query, false, "Expected no images without a genotype.");
}

function testEndpointHasImagesWithSpecificGenotype(testcase, genotype) {
	var query = "ASK {?image dro:genotype dro:"+genotype+"}";
	var message = "There should be at least one image for genotype '"+genotype+"'.";
	testAskQuery("flyted", testcase, query, true, message);
}

function testEndpointHasImageWithExpressions(testcase) {
	var query = "ASK { ?image rdf:type dro:Image ; dro:expression ?expression . }";
	testAskQuery("flyted", testcase, query, true, "Expected images with an expression location.");
}

function testEndpointHasImagesWithSpecificExpression(testcase, expression) {
	var query = "ASK {?image dro:expression \""+expression+"\"}";
	var message = "There should be at least one image for expression '"+expression+"'.";
	testAskQuery("flyted", testcase, query, true, message);
}

function testEndpointHasImageWithSomaticExpressions(testcase) {
	var query = "ASK { ?image rdf:type dro:Image ; dro:somatic ?somatic . }";
	testAskQuery("flyted", testcase, query, true, "Expected images with a somatic expression location.");
}

function testEndpointHasImagesWithSpecificSomaticExpression(testcase, expression) {
	var query = "ASK {?image dro:somatic \""+expression+"\"}";
	var message = "There should be at least one image for somatic expression '"+expression+"'.";
	testAskQuery("flyted", testcase, query, true, message);
}

function testEndpointHasTheRightNumberOfImages(testcase){
	var query = "select distinct ?image where {?image rdf:type dro:Image}";
	var failureMessage = "There should be 1947 images.";
	
	var callback = {
			success: testSelectQueryExpectNumBindingsResponseSuccess(testcase, 1947, failureMessage),
			failure: genericResponseFailure(testcase)
		};
		
	// define SPARQL query & URL
	query = sparqlns + query;
	var url = "flyted?output=json&query=" + escape(query);
	log("Unescaped query: "+query);
		
	log("Make the request to "+url);
	var request = YAHOO.util.Connect.asyncRequest("GET", url, callback, null);
		
	log("Suspend the test runner");
	testcase.wait();
}


/* Comment out because we have to live with images that are missing an expression location.
function testEndpointHasNoImagesWithoutExpressions (testcase) {
	
	var query = "ASK { ?image rdf:type dro:Image . OPTIONAL {?image dro:expression ?expression }. FILTER ( !bound(?expression)) }";
	testAskQuery("flyted", testcase, query, false, "Expected no images without an expression location.");
		
}

function testEndpointHasNoImagesWithoutExpressionsAndLogThemIfTheyDont (testcase) {
	var query = sparqlns + "Select ?image { ?image rdf:type dro:Image . OPTIONAL {?image dro:expression ?expression }. FILTER ( !bound(?expression)) }";
	testSelectQueryExpectNoBindings("flyted", testcase, query, "Expected no images without an expression location.");
}
*/


var flytedTestCase = new YAHOO.tool.TestCase({

	name: "FlyTED SPARQL Endpoint Test Case",
	
	testEndpointExists : function() {
		testEndpointExists(this);
	},
	
	testEndpointHasData : function() {
		testEndpointHasData(this);
	},
	
	testEndpointHasImages : function() {
		testEndpointHasImages(this);
	},
	
	testEndpointImageURIsAreValid : function() {
		testEndpointImageURIsAreValid(this);
	},
	
	testEndpointHasImagesWithGeneNames : function() {
		testEndpointHasImagesWithGeneNames(this);
	},
	
	testEndpointHasNoImagesWithoutGeneNames : function() {
		testEndpointHasNoImagesWithoutGeneNames(this);
	},
	
	testEndpointHasImagesWithGeneNameAdh : function() {
		testEndpointHasImagesWithSpecificGeneName(this,"Adh");
	},
	
	testEndpointHasImagesWithGeneNameCG10151 : function() {
		testEndpointHasImagesWithSpecificGeneName(this,"CG10151");
	},
	
	testEndpointHasImageWithThumbnails : function() {
		testEndpointHasImageWithThumbnails(this);
	},
	
	testEndpointHasNoImagesWithoutThumbnails : function() {
		testEndpointHasNoImagesWithoutThumbnails(this);
	},

	testEndpointHasImageWithSeeAlso : function(){ 
		testEndpointHasImageWithSeeAlso (this);
	},
	
	testEndpointHasNoImagesWithoutSeeAlso : function() {
		testEndpointHasNoImagesWithoutSeeAlso (this);
	},
	
	testEndpointHasImageWithGenotype : function() {
		testEndpointHasImageWithGenotype(this);
	},
	
	testEndpointHasNoImagesWithoutGenotype : function() {
		testEndpointHasNoImagesWithoutGenotype(this);
	},
	
	testEndpointHasImagesWithSpecificGenotypeWt : function(){
		testEndpointHasImagesWithSpecificGenotype (this, "wt");
	},
	
	testEndpointHasImagesWithSpecificGenotypeAly : function(){
		testEndpointHasImagesWithSpecificGenotype (this, "aly");
	},
	
	testEndpointHasImageWithExpressions : function () {
		testEndpointHasImageWithExpressions (this);
	},
	
	testEndpointHasImagesWithSpecificExpressionWithNoStraining : function() {
		testEndpointHasImagesWithSpecificExpression (this, "No_staining");
	},
	
	testEndpointHasImagesWithSpecificExpressionWithEarlyPrimarySpermatocytes : function() {
		testEndpointHasImagesWithSpecificExpression (this, "early_primary_spermatocytes");
	}, 
	
	testEndpointHasImagesWithSpecificExpressionLateCystCells : function() {
		testEndpointHasImagesWithSpecificExpression (this, "Late_cyst_cells");
	}, 
	
	testEndpointHasImageWithSomaticExpressions : function() {
		testEndpointHasImageWithSomaticExpressions(this);
	},
	
	testEndpointHasImagesWithSpecificSomaticExpressionLateCystCells : function() {
		testEndpointHasImagesWithSpecificExpression (this, "Late_cyst_cells");
	},
	
	testEndpointHasImagesWithSpecificSomaticExpressionAccessoryGlands : function() {
		testEndpointHasImagesWithSpecificExpression (this, "Accessory_glands");
	}, 
	
	testEndpointHasTheRightNumberOfImages : function() {
		testEndpointHasTheRightNumberOfImages(this);
	}
	
})	

function setupLogger() {
	var logReader = new YAHOO.tool.TestLogger("logger");
	YAHOO.log("Logger setup done");	
}

function runTests() {
	YAHOO.log("Running tests");
	YAHOO.tool.TestRunner.add(flytedTestCase);
	YAHOO.tool.TestRunner.run();
}

YAHOO.util.Event.onDOMReady(setupLogger);
YAHOO.util.Event.onDOMReady(runTests);

